package com.css.devops.service.jenkins;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.css.devops.domain.JobStatistics;
import com.css.devops.service.DevopsJob;
import com.google.common.collect.Lists;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.Build;
import com.offbytwo.jenkins.model.Job;
import com.offbytwo.jenkins.model.JobWithDetails;
import com.offbytwo.jenkins.model.MavenJobWithDetails;

import lombok.extern.slf4j.Slf4j;

/**
 * Job(任务) 相关操作
 *
 * 例如对任务的增、删、改、查等操作
 */
@Slf4j
@Service("jenkinsJobService")
public class JenkinsJobService implements DevopsJob {

    /**
     * Jenkins 对象
     */
	@Autowired
    private JenkinsServer jenkinsServer;
	
	@Autowired
	private JenkinsBuildMonitorService jenkinsBuildMonitorService;
	
    /**
     * 创建 Job
     */
    @Override
	public void ceateJob(com.css.devops.domain.Job job){
        try {
//        	String script = "node(){ \n" +
//                    "echo 'hello world!' \n" +
//                "}";
            /**创建一个流水线任务，且设置一个简单的脚本**/
            // xml配置文件，且将脚本加入到配置中
            String xml = "<flow-definition plugin=\"workflow-job@2.32\">\n" +
                             "<description>%s</description>\n" +
                             "<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\" plugin=\"workflow-cps@2.66\">\n" +
                                 "<script>%s</script>\n" +
                                 "<sandbox>true</sandbox>\n" +
                             "</definition>\n" +
                          "</flow-definition>";
            xml = String.format(xml, job.getScript(), job.getScript());
            // 创建 Job
            jenkinsServer.createJob(job.getName(),xml,Boolean.TRUE);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }
    

    /**
     * 更新 Job
     *
     * 更改之前创建的无参数Job，更改其为参数Job
     */
    @Override
	public void updateJob(com.css.devops.domain.Job job){
        try {
            /**
             * 更改一个流水线任务，让一个无参数的任务变成带参数任务
             */
            // 创建 Pipeline 脚本，用一个key变量
//            String script = "node(){ \n" +
//                    "echo \"${key}\" \n" +
//                    "}";
            // xml配置文件，且将脚本加入到配置中
            String xml = "<flow-definition plugin=\"workflow-job@2.32\">\n" +
                    "<actions/>\n" +
                    "<description>%s</description>\n" +
                    "<keepDependencies>false</keepDependencies>\n" +
                    "<properties>\n" +
                    "<hudson.model.ParametersDefinitionProperty>\n" +
                    "<parameterDefinitions>\n" +
                    "<hudson.model.StringParameterDefinition>\n" +
                    "<name>key</name>\n" +
                    "<description>%s</description>\n" +
                    "<defaultValue>hello</defaultValue>\n" +
                    "<trim>false</trim>\n" +
                    "</hudson.model.StringParameterDefinition>\n" +
                    "</parameterDefinitions>\n" +
                    "</hudson.model.ParametersDefinitionProperty>\n" +
                    "</properties>\n" +
                    "<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\" plugin=\"workflow-cps@2.66\">\n" +
                    "<script>%s</script>\n" +
                    "<sandbox>true</sandbox>\n" +
                    "</definition>\n" +
                    "<disabled>false</disabled>\n" +
                    "</flow-definition>";
            xml = String.format(xml, job.getName(),job.getDescription(),job.getScript());
            // 修改 Job
            jenkinsServer.updateJob(job.getName(),xml,true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 获取 Job 基本信息
     */
    @Override
	public com.css.devops.domain.Job getJob(String jobName){
    	com.css.devops.domain.Job responseJob = null;
        try {
            // 获取 Job 信息
            JobWithDetails job = jenkinsServer.getJob(jobName);
            responseJob = new com.css.devops.domain.Job();
            responseJob.setName(job.getName());
            responseJob.setDescription(job.getDescription());
            responseJob.setScript(job.getUrl());
            responseJob.setNextBuildNumber(job.getNextBuildNumber());
            responseJob.setDisplayName(job.getDisplayName());
//            // 获取 Job 名称
//            System.out.println(job.getName());
//            // 获取 Job URL
//            System.out.println(job.getUrl());
//            // 获取 Job 下一个 build 编号
//            System.out.println(job.getNextBuildNumber());
//            // 获取 Job 显示的名称
//            System.out.println(job.getDisplayName());
//            // 输出 Job 描述信息
//            System.out.println(job.getDescription());
//            // 获取 Job 下游任务列表
//            System.out.println(job.getDownstreamProjects());
//            // 获取 Job 上游任务列表
//            System.out.println(job.getUpstreamProjects());
            JobStatistics jobStatistics = jenkinsBuildMonitorService.statisticsJob(job.getName());
            responseJob.setJobStatistics(jobStatistics);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
        return responseJob;
    }

    /**
     * 获取 Maven Job 信息
     */
    @Override
	public void getMavenJob(){
        try {
            // 获取 Job 信息
            MavenJobWithDetails job = jenkinsServer.getMavenJob("test-job");
            System.out.println(job.getDisplayName());
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 获取 Job 列表
     */
    @Override
	public List<com.css.devops.domain.Job> getJobList(){
    	List<com.css.devops.domain.Job> responseJobs = Lists.newArrayList();
        try {
            // 获取 Job 列表
            Map<String,Job> jobs = jenkinsServer.getJobs();
            for (Job job : jobs.values()){
            	com.css.devops.domain.Job responseJob = new com.css.devops.domain.Job();
            	
            	JobWithDetails jobWithDetails = jenkinsServer.getJob(job.getName());
                responseJob.setName(jobWithDetails.getName());
                responseJob.setDescription(jobWithDetails.getDescription());
                responseJob.setUrl(jobWithDetails.getUrl());
                responseJob.setNextBuildNumber(jobWithDetails.getNextBuildNumber());
                responseJob.setDisplayName(jobWithDetails.getDisplayName());
                
                JobStatistics jobStatistics = jenkinsBuildMonitorService.statisticsJob(job.getName());
                responseJob.setJobStatistics(jobStatistics);
                
            	responseJobs.add(responseJob);
            }
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
        return responseJobs;
    }

    /**
     * 获取 View 名称获取 Job 列表
     */
    @Override
	public List<com.css.devops.domain.Job> getJobListByView(String viewName){
    	List<com.css.devops.domain.Job> responseJobs = Lists.newArrayList();
        try {
            // 获取 Job 列表
            Map<String,Job> jobs = jenkinsServer.getJobs(viewName);
            for (Job job : jobs.values()){
            	com.css.devops.domain.Job responseJob = new com.css.devops.domain.Job();
            	
            	JobWithDetails jobWithDetails = jenkinsServer.getJob(job.getName());
                responseJob.setName(jobWithDetails.getName());
                responseJob.setDescription(jobWithDetails.getDescription());
                responseJob.setScript(jobWithDetails.getUrl());
                responseJob.setNextBuildNumber(jobWithDetails.getNextBuildNumber());
                responseJob.setDisplayName(jobWithDetails.getDisplayName());
                
                JobStatistics jobStatistics = jenkinsBuildMonitorService.statisticsJob(job.getName());
                responseJob.setJobStatistics(jobStatistics);
                
            	responseJobs.add(responseJob);
            }
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
        return responseJobs;
    }

    /**
     * 查看 Job XML 信息
     */
    @Override
	public String getJobConfig(String jobName){
    	String xml = StringUtils.EMPTY;
        try {
            xml = jenkinsServer.getJobXml(jobName);
            System.out.println(xml);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
        return xml;
    }

    /**
     * 执行无参数 Job build
     */
    @Override
	public void buildJob(String jobName){
        try {
        	JobWithDetails jobWithDetails = jenkinsServer.getJob(jobName);
        	jobWithDetails.build(true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 执行带参数 Job build
     */
    @Override
	public void buildParamJob(String jobName,Map<String,String> param){
        try {
            /**
             * 例如，现有一个job，拥有一个字符参数"key"
             * 现在对这个值进行设置，然后执行一个输出这个值的脚本
             */
            // 执行 build 任务
            jenkinsServer.getJob(jobName).build(param,true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 停止最后构建的 Job Build
     */
    @Override
	public void stopLastJobBuild(String jobName){
        try {
            // 获取最后的 build 信息
            Build build = jenkinsServer.getJob(jobName).getLastBuild();
            // 停止最后的 build
            build.Stop(true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 删除 Job
     */
    @Override
	public void deleteJob(String jobName){
        try {
            jenkinsServer.deleteJob(jobName,true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 禁用 Job
     */
    @Override
	public void disableJob(String jobName){
        try {
            jenkinsServer.disableJob(jobName,true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 启用 Job
     */
    @Override
	public void enableJob(String jobName){
        try {
            jenkinsServer.enableJob(jobName,true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

}
